﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace HDSmartCommunity.BUS.MqttBUS
{

    public class MqttDevices : IMqttDevices
    {
        MqttClientBUS BUS;
        ConcurrentDictionary<string, TaskDevice> tasks;
        public MqttDevices()
        {
            BUS = new MqttClientBUS();
            tasks = new ConcurrentDictionary<string, TaskDevice>();
        }

        public string StartAsync(string DeviceID)
        {
            if (!tasks.ContainsKey(DeviceID))
            {
                try
                {
                    RunPublicMessageTask(DeviceID);
                }
                catch (Exception e)
                {
                    return e.ToString();
                }
            }
            else
            {
                TaskDevice device = new TaskDevice();
                device = tasks.GetOrAdd(DeviceID, device);
                device.Count++;
            }
            return "";
        }

        public string StopAsync(string deviceID)
        {
            if (tasks.ContainsKey(deviceID))
            {
                try
                {
                    TaskDevice device = new TaskDevice();
                    device = tasks.GetOrAdd(deviceID, device);
                    if (device.Count <= 1)
                    {
                        device.TokenSource.Cancel();
                        tasks.TryRemove(deviceID, out device);
                    }
                    else device.Count--;
                }
                catch (Exception e)
                {
                    return e.ToString();
                }
            }
            return "";
        }
        public string StopFromUserNameAsync(string DeviceID)
        {
            foreach (var keyValuePair in tasks)
            {
                if (keyValuePair.Value.DeviceID.Equals(DeviceID))
                {
                    StopAsync(keyValuePair.Key);
                }
            }
            return "";
        }

        private void RunPublicMessageTask(string DeviceID)
        {
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            CancellationToken token = tokenSource.Token;
            Task t = Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    await BUS.PublicMessage("Liftstate-" + DeviceID, "111111", 1);

                    Task.Delay(1500).Wait();
                }
            }, token);

            if (!t.IsCanceled)
            {
                TaskDevice taskDevices = new TaskDevice();
                taskDevices.t = t;
                taskDevices.Count = 1;
                taskDevices.TokenSource = tokenSource;
                tasks.AddOrUpdate(DeviceID, taskDevices, (id, taskDevice) =>
                {
                    taskDevice.Count++;
                    return taskDevice;
                });
            }
        }
    }

}
